#include "DualCalendars.h"
#include <QColor>
#include <QHBoxLayout>
#include <core/StyleMgr.h>
#include <QStylePainter>
#include <QRect>
#include <QMenu>
#include <QToolButton>
#include <QTableView>
#include <QTextCharFormat>
#include <QCoreApplication>

SCalendar::SCalendar(QWidget* parent /*= nullptr*/)
{
	this->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader);
	this->setDateEditEnabled(false);//取消通过键盘输入日期操作

	QTextCharFormat f = this->weekdayTextFormat(Qt::Monday);//获取周一字体格式,周六周日颜色需要特殊设置
	f.setForeground(QBrush(QColor("#FFEBC8")));//替换字体颜色
	QTextCharFormat weekdays = f;
	this->setWeekdayTextFormat(Qt::Sunday, weekdays);
	this->setWeekdayTextFormat(Qt::Saturday, weekdays);

	QString m_styleSheet = QString(
		"QToolButton#qt_calendar_monthbutton,#qt_calendar_yearbutton	{color: #%1;}"
		"QCalendarWidget QWidget#qt_calendar_navigationbar				{background-color: #%2;}"
		"QCalendarWidget QAbstractItemView:enabled						{color: #%1;background-color: #%2;selection-background-color: #%3;selection-color: #%4;outline: none;}"
		"QCalendarWidget QAbstractItemView::item:hover					{background-color:#%3;}"
		"QCalendarWidget QTableView									    {alternate-background-color: #%2;}"
		"QCalendarWidget QSpinBox#qt_calendar_yearedit					{background:#%2;height:20px;width:30px;selection-background-color:#%2;color:#%4;}"
		"QCalendarWidget QSpinBox::up-button							{subcontrol-origin: margin; subcontrol-position:top right; width:20px;}"
		"QCalendarWidget QSpinBox::down-button							{subcontrol-origin: margin; subcontrol-position:bottom right; width:20px;}"
		"QCalendarWidget QToolButton::menu-indicator#qt_calendar_monthbutton {width:7px;subcontrol-position:right;subcontrol-origin:margin;}"
		"QToolButton#qt_calendar_prevmonth								{icon-size:30px; qproperty-icon:url(:/widgets/image/calendar_month/calendar_month_left_normal.png);}"
		"QToolButton#qt_calendar_nextmonth								{icon-size:30px; qproperty-icon:url(:/widgets/image/calendar_month/calendar_month_right_normal.png);}"
	)
		.arg(StyleMgr::instance().color("TextNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("Hover").rgb(), 0, 16)
		.arg(StyleMgr::instance().color("Highlight").rgb(), 0, 16);

	setStyleSheet(m_styleSheet);
	for (auto each : this->findChildren<QTableView*>())
	{
		each->viewport()->installEventFilter(this);
	}
}

SCalendar::~SCalendar()
{

}

void SCalendar::paintCell(QPainter* painter, const QRect& rect, const QDate& date) const
{
	QColor bgColor = StyleMgr::instance().color("BackNormal");
	QColor ndColor = StyleMgr::instance().color("SupportingWord");
	QColor dayColor	= StyleMgr::instance().color("TextNormal");
	QColor tdColor = StyleMgr::instance().color("Green05");
	tdColor.setAlpha(200);

	painter->setPen(bgColor);

	QDate currentDay(QDate::currentDate());
	if (currentDay == date)
	{
		painter->setBrush(tdColor);
		painter->drawRect(rect);
	}

	if (date == _start && date != _end && this->monthShown() == date.month())
	{
		painter->setBrush(QColor(19, 62, 56, 200));
		painter->drawRect(rect);
	}
	if (date == _end && date == _start && this->monthShown() == date.month() && date.isValid())
	{
		painter->setBrush(QColor(19, 62, 56, 200));
		painter->drawRect(rect);
	}
	else if (date == _end && date != _start && this->monthShown() == date.month())
	{
		painter->setBrush(QColor(19, 62, 56, 200));
		painter->drawRect(rect);
	}
	if (_colorStart.isValid() && _colorEnd.isValid() && date <= _colorEnd && date >= _colorStart && this->monthShown() == date.month())
	{
		painter->setBrush(QColor(19, 62, 56, 200));
		painter->drawRect(rect);
	}
	painter->setBrush(bgColor);
	this->monthShown() == date.month() ? painter->setPen(dayColor) : painter->setPen(ndColor);
	painter->drawText(rect, Qt::AlignHCenter | Qt::AlignVCenter, QString::number(date.day()));
}

void SCalendar::setStart(const QDate& start)
{
	_start = start;
	updateCells();
}

void SCalendar::setEnd(const QDate& end)
{
	_end = end;
	updateCells();
}

void SCalendar::setSelectedColorBetweenTwoDatas(QDate start, QDate end)
{
	_colorStart = start;
	_colorEnd = end;
	updateCells();
}

bool SCalendar::eventFilter(QObject* obj, QEvent* event)
{
	if (event->type() == QEvent::Wheel)
	{
		return true;
	}
	else
	{
		return QWidget::eventFilter(obj, event);
	}
}

DualCalendars::DualCalendars(QWidget* parent /*= nullptr*/)
	: QFrame(parent, Qt::ToolTip | Qt::BypassGraphicsProxyWidget)
{
	calL = new SCalendar();
	calR = new SCalendar();

	QToolButton* calLMonthButton = calL->findChild<QToolButton*>(QLatin1String("qt_calendar_monthbutton"));
	QToolButton* calRMonthButton = calR->findChild<QToolButton*>(QLatin1String("qt_calendar_monthbutton"));
	calLmenu = calLMonthButton->menu();
	calRmenu = calRMonthButton->menu();

	QHBoxLayout* layout = new QHBoxLayout(this);
	layout->addWidget(calL);
	layout->addWidget(calR);

	setFixedSize(455,238);
	setStyleSheet(QString("background-color:#%1").arg(StyleMgr::instance().color("BackNormal").rgb(), 0, 16));
	setConnection();
	qApp->installEventFilter(this);
}

DualCalendars::~DualCalendars()
{

}

void DualCalendars::setConnection()
{
	connect(calLmenu, &QMenu::aboutToShow, this, &DualCalendars::onMenuShow);
	connect(calRmenu, &QMenu::aboutToShow, this, &DualCalendars::onMenuShow);

	connect(calLmenu, &QMenu::aboutToHide, this, &DualCalendars::onMenuHide);
	connect(calRmenu, &QMenu::aboutToHide, this, &DualCalendars::onMenuHide);

	//选定日期跟随变化
	connect(calL, &QCalendarWidget::clicked, [=](QDate date) {
		onrlClicked(std::make_pair<QString, QDate>("left", std::move(date)));
		});
	connect(calR, &QCalendarWidget::clicked, [=](QDate date) {
		onrlClicked(std::make_pair<QString, QDate>("right", std::move(date)));
		});

}

void DualCalendars::setStartEndDate(QDate start, QDate end)
{
	QString startDay = start.toString("yyyyMMdd");
	QString endDay = end.toString("yyyyMMdd");

	int sDay = startDay.toInt();
	int eDay = endDay.toInt();
	
	if (sDay > eDay) std::swap(sDay, eDay);
	
	emit StartEndDatedSelected(sDay,eDay);
}

void DualCalendars::hideAfterSelected()
{
	if (isShow)
		hide();
}

bool DualCalendars::eventFilter(QObject* obj, QEvent* event)
{
	switch (event->type()) 
	{
		case QEvent::MouseButtonPress:
		case QEvent::MouseButtonRelease:
		case QEvent::MouseButtonDblClick:
		{
			if (isMenuShow)
			{
				return false;
			}
			else
			{
				QMouseEvent* me = dynamic_cast<QMouseEvent*>(event);
				if (!rect().contains(mapFromGlobal(me->globalPos())))
				{
					hide();
				}
			}
		}
			break;
		default:
			break;
	}
	return false;
}

void DualCalendars::paintEvent(QPaintEvent*)
{
	QStylePainter painter(this);
	QPen pen(StyleMgr::instance().color("BorderNormal"));
	int r = StyleMgr::instance().size("RoundCorner");

	painter.setRenderHint(QPainter::Antialiasing);
	painter.setPen(pen);

	painter.drawRoundedRect(rect(), r, r);
}

void DualCalendars::onrlClicked(std::pair<QString, QDate> info)
{
	//清空标注;
	QDate date;
	calL->setStart(date);
	calR->setStart(date);
	calL->setEnd(date);
	calR->setEnd(date);

	if (selectedDate.dateCountSelected() == 1)
	{
		selectedDate.dateSelected.push_back(info);
		if (selectedDate.dateSelected[0].second >= info.second)
		{
			if (selectedDate.dateSelected[0].first == "left")
			{
				calL->setEnd(selectedDate.dateSelected[0].second);
				calR->setEnd(selectedDate.dateSelected[0].second);
			}
			else
			{
				calR->setEnd(selectedDate.dateSelected[0].second);
				calL->setEnd(selectedDate.dateSelected[0].second);
			}
			if (info.first == "right")
			{
				calR->setStart(info.second);
				calL->setStart(info.second);
			}
			else
			{
				calL->setStart(info.second);
				calR->setStart(info.second);
			}
			calL->setSelectedColorBetweenTwoDatas(info.second, selectedDate.dateSelected[0].second);
			calR->setSelectedColorBetweenTwoDatas(info.second, selectedDate.dateSelected[0].second);
		}
		else
		{
			if (selectedDate.dateSelected[0].first == "left")
			{
				calL->setStart(selectedDate.dateSelected[0].second);
				calR->setStart(selectedDate.dateSelected[0].second);
			}
			else
			{
				calR->setStart(selectedDate.dateSelected[0].second);
				calL->setStart(selectedDate.dateSelected[0].second);
			}
			if (info.first == "right")
			{
				calR->setEnd(info.second);
				calL->setEnd(info.second);
			}
			else
			{
				calL->setEnd(info.second);
				calR->setEnd(info.second);
			}
			calL->setSelectedColorBetweenTwoDatas(selectedDate.dateSelected[0].second, info.second);
			calR->setSelectedColorBetweenTwoDatas(selectedDate.dateSelected[0].second, info.second);
		}
		//调用选择结束，中间单元格上色，选择结果生成
		isShow = true;
		if (calR->monthShown() <= calL->monthShown() || calR->yearShown() < calL->yearShown())
		{
			isShow = false;
		}
		if (selectedDate.dateSelected[0].first == "left" && info.first == "right"
			&& selectedDate.dateSelected[0].second > info.second)
		{
			isShow = false;
		}
		
		if (isShow) //是合法日期再准备发送信号
			setStartEndDate(selectedDate.dateSelected[0].second, info.second);

		hideAfterSelected();
	}
	else
	{
		selectedDate.clear();
		//清除原有标注
		calL->setSelectedColorBetweenTwoDatas(QDate(), QDate());
		calR->setSelectedColorBetweenTwoDatas(QDate(), QDate());
		//加入第一个点，等待第二个点
		selectedDate.dateSelected.push_back(info);
		info.first == "left" ? calL->setStart(info.second) : calR->setStart(info.second);
	}
}
void DualCalendars::onMenuShow()
{
	isMenuShow = true;
}

void DualCalendars::onMenuHide()
{
	isMenuShow = false;
}

